using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CPlatePrintSys.DataAccess.Context;
using CPlatePrintSys.Domain.Models;
using CPlatePrintSys.Infrastructure.Repositories;

namespace CPlatePrintSys.DataAccess.Repositories
{
    public class PlateAnnotationInfoRepository : IPlateAnnotationInfoRepository
    {
        private readonly CPlateDbContext _context;
        public PlateAnnotationInfoRepository(CPlateDbContext context)
        {
            _context = context;
        }

        public async Task<PlateAnnotationInfo> GetByIdAsync(object id)
            => await _context.PlateAnnotationInfos.FindAsync(id);

        public async Task<IEnumerable<PlateAnnotationInfo>> GetAllAsync()
            => await _context.PlateAnnotationInfos.ToListAsync();

        public async Task<PlateAnnotationInfo> AddAsync(PlateAnnotationInfo entity)
        {
            _context.PlateAnnotationInfos.Add(entity);
            await _context.SaveChangesAsync();
            return entity;
        }

        public async Task UpdateAsync(PlateAnnotationInfo entity)
        {
            var dbEntity = await _context.PlateAnnotationInfos.FindAsync(entity.Id);
            if (dbEntity == null) throw new Exception("未找到对应标注信息");
            _context.Entry(dbEntity).CurrentValues.SetValues(entity);
            await _context.SaveChangesAsync();
        }

        public async Task DeleteAsync(object id)
        {
            var entity = await _context.PlateAnnotationInfos.FindAsync(id);
            if (entity != null)
            {
                _context.PlateAnnotationInfos.Remove(entity);
                await _context.SaveChangesAsync();
            }
        }

        public async Task<IEnumerable<PlateAnnotationInfo>> FindAsync(Expression<Func<PlateAnnotationInfo, bool>> predicate)
            => await _context.PlateAnnotationInfos.Where(predicate).ToListAsync();

        public async Task<int> CountAsync(Expression<Func<PlateAnnotationInfo, bool>> predicate = null)
        {
            if (predicate == null)
                return await _context.PlateAnnotationInfos.CountAsync();
            return await _context.PlateAnnotationInfos.CountAsync(predicate);
        }

        public async Task<PlateAnnotationInfo> GetByUniqueKeyAsync(string streamShipNo, string lotNo, string sequence)
        {
            return await _context.PlateAnnotationInfos.FirstOrDefaultAsync(p =>
                p.StreamShipNo == streamShipNo &&
                p.LotNo == lotNo &&
                p.Sequence == sequence);
        }

        public async Task<PlateAnnotationInfo> AddIfNotExistsAsync(PlateAnnotationInfo entity)
        {
            var existing = await GetByUniqueKeyAsync(entity.StreamShipNo, entity.LotNo, entity.Sequence);
            if (existing != null)
                return existing;
            _context.PlateAnnotationInfos.Add(entity);
            await _context.SaveChangesAsync();
            return entity;
        }

        public async Task<int> UpdateMotherShipNoAsync(string oldMotherShipNo, string newMotherShipNo)
        {
            var records = await _context.PlateAnnotationInfos
                .Where(p => p.MotherShipNo == oldMotherShipNo)
                .ToListAsync();

            foreach (var record in records)
            {
                record.MotherShipNo = newMotherShipNo;
            }

            return await _context.SaveChangesAsync();
        }

        public async Task<int> UpdateStreamShipNoAsync(string oldStreamShipNo, string newStreamShipNo)
        {
            var records = await _context.PlateAnnotationInfos
                .Where(p => p.StreamShipNo == oldStreamShipNo)
                .ToListAsync();

            foreach (var record in records)
            {
                record.StreamShipNo = newStreamShipNo;
            }

            return await _context.SaveChangesAsync();
        }

        public async Task<int> DeleteByMotherShipNoAsync(string motherShipNo)
        {
            var records = await _context.PlateAnnotationInfos
                .Where(p => p.MotherShipNo == motherShipNo)
                .ToListAsync();

            foreach (var record in records)
            {
                _context.PlateAnnotationInfos.Remove(record);
            }

            return await _context.SaveChangesAsync();
        }

        public async Task<int> DeleteByStreamShipNoAsync(string streamShipNo)
        {
            var records = await _context.PlateAnnotationInfos
                .Where(p => p.StreamShipNo == streamShipNo)
                .ToListAsync();

            foreach (var record in records)
            {
                _context.PlateAnnotationInfos.Remove(record);
            }

            return await _context.SaveChangesAsync();
        }

        public async Task UpdateAnnotationDrawingPathAsync(int id, string annotationDrawingPath)
        {
            var entity = await _context.PlateAnnotationInfos.FindAsync(id);
            if (entity != null)
            {
                entity.AnnotationDrawingPath = annotationDrawingPath;
                await _context.SaveChangesAsync();
            }
        }
    }
} 